﻿using DetectingKinectSencor._40_Tools;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace DetectingKinectSencor
{
    /// <summary>
    /// Interaktionslogik für PropertiesWindow.xaml
    /// </summary>
    public partial class PropertiesWindow : Window
    {
        private bool noError;

        static string pattern = ",";
        static string replacementDot = ".";

        static Regex replaceComma = new Regex(pattern);


        public PropertiesWindow()
        {
            InitializeComponent();
        }

        #region ScaleValue Depdency Property
        public static readonly DependencyProperty ScaleValueProperty = DependencyProperty.Register("ScaleValue", typeof(double), typeof(PropertiesWindow), new UIPropertyMetadata(1.0, new PropertyChangedCallback(OnScaleValueChanged), new CoerceValueCallback(OnCoerceScaleValue)));


        private static object OnCoerceScaleValue(DependencyObject o, object value)
        {
            PropertiesWindow mainWindow = o as PropertiesWindow;
            if (mainWindow != null)
                return mainWindow.OnCoerceScaleValue((double)value);
            else
                return value;
        }

        private static void OnScaleValueChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            PropertiesWindow mainWindow = o as PropertiesWindow;
            if (mainWindow != null)
                mainWindow.OnScaleValueChanged((double)e.OldValue, (double)e.NewValue);
        }

        protected virtual double OnCoerceScaleValue(double value)
        {
            if (double.IsNaN(value))
                return 1.0f;

            value = Math.Max(0.1, value);
            return value;
        }

        protected virtual void OnScaleValueChanged(double oldValue, double newValue)
        {

        }

        public double ScaleValue
        {
            get
            {
                return (double)GetValue(ScaleValueProperty);
            }
            set
            {
                SetValue(ScaleValueProperty, value);
            }
        }
        #endregion

        private void MainGrid_SizeChanged(object sender, EventArgs e)
        {
            CalculateScale();
        }

        private void CalculateScale()
        {
            double yScale = ActualHeight / 515;
            double xScale = ActualWidth / 750;
            double value = Math.Min(xScale, yScale);
            ScaleValue = (double)OnCoerceScaleValue(MainGrid, value);
        }



        public void initializeProperties()
        {
            // Body Language
            offsetViewingDirectionTXT.Text = replaceComma.Replace(XMLproperties.offsetViewingDirection.ToString(),replacementDot);
            secondsTillLookedAwayDetectedTXT.Text = replaceComma.Replace(XMLproperties.secondsLookedAwayDetected.ToString(),replacementDot);

            offsetMovementManagerTXT.Text = replaceComma.Replace(XMLproperties.offsetMovementManager.ToString(),replacementDot);
            secondsTillMovingDetectedTXT.Text = replaceComma.Replace(XMLproperties.secondsTillMovingDetected.ToString(),replacementDot);

            offsetOpenGestureTXT.Text = replaceComma.Replace(XMLproperties.offsetOpenGesture.ToString(),replacementDot);
            milliSecondsTillOpenGestureDetectedTXT.Text = replaceComma.Replace(XMLproperties.milliSecondsTillOpenGestureDetected.ToString(),replacementDot);

            offsetHandsBelowWaistLineTXT.Text = replaceComma.Replace(XMLproperties.offsetHandsBelowWaistline.ToString(),replacementDot);
            SecondsTillHandBelowWaistLineDetectedTXT.Text = replaceComma.Replace(XMLproperties.secondsTillHandsBelowwastelineDetected.ToString(),replacementDot);




            // Slides

            offsetSlideChangeTXT.Text = replaceComma.Replace(XMLproperties.offsetSlidesChange.ToString(),replacementDot);
            requiredAveragesToDetectVideoTXT.Text = replaceComma.Replace(XMLproperties.requiredAveragesToDetectVideo.ToString(), replacementDot);
            offsetSkeletonPositionTXT.Text = replaceComma.Replace(XMLproperties.offsetSkeletonPosition.ToString(),replacementDot);
            offsetImageDetectedTXT.Text = replaceComma.Replace(XMLproperties.thresholdImageDetected.ToString(),replacementDot);

            secondsTillSnapshotTXT.Text = replaceComma.Replace(XMLproperties.secondsTillSnapshot.ToString(), replacementDot);
            offsetVideoDetectedTXT.Text = replaceComma.Replace(XMLproperties.thresholdVideoDetected.ToString(), replacementDot);

            thresholdToCalculateOffestForNewShoulderPositionTXT.Text = replaceComma.Replace(XMLproperties.thresholdToCalculateOffestForNewShoulderPosition.ToString(), replacementDot);

            offsetHipSkeletonPositionTXT.Text = replaceComma.Replace(XMLproperties.offsetHipSkeletonPosition.ToString(), replacementDot);

            thresholdChangeBorderOfRectangleTXT.Text = replaceComma.Replace(XMLproperties.thresholdChangeBorderOfRectangle.ToString(), replacementDot);
        }

        private void saveProperties_Click(object sender, RoutedEventArgs e)
        {
            float tempOffsetViewingDirection;
            float tempSecondsTillLookedAwayDetected;
            float tempOffsetMovementManager;
            float tempSecondsTillMovingDetected;
            float tempOffsetOpenGesture;
            int tempMillisecondsTillOpenGestureDetected;
            float tempOffsetHandsBelowWaistLine;
            float tempSecondsTillHandBelowWaistLineDetected;
            int tempOffsetSlideChange;
            int tempRequiredAveragesToDetectVideo;
            int tempOffsetSkeletonPosition;
            float tempOffsetImageDetected;
            int tempSecondsTillSnapshot;
            float tempOffsetVideoDetected;
            float tempThresholdToCalculateOffestForNewShoulderPosition;
            int tempOffsetHipSkeletonPosition;
            int tempThresholdChangeBorderOfRectangle;
            noError = true;
            
            // Body Language
            tempOffsetViewingDirection = float.Parse(offsetViewingDirectionTXT.Text, CultureInfo.InvariantCulture);


            if (tempOffsetViewingDirection < 0.0 || tempOffsetViewingDirection > 2.0)
            {
                noError = false;
                MessageBox.Show("Number needs to be between 0.0 and 2.0");
            }


            tempSecondsTillLookedAwayDetected = float.Parse(secondsTillLookedAwayDetectedTXT.Text, CultureInfo.InvariantCulture);

            if (tempSecondsTillLookedAwayDetected < 0.0 || tempSecondsTillLookedAwayDetected > 10.0)
            {
                noError = false;
                MessageBox.Show("Number needs to be between 0.0 and 10.0");
            }


            tempOffsetMovementManager = float.Parse(offsetMovementManagerTXT.Text, CultureInfo.InvariantCulture);

            if (tempOffsetMovementManager < 0.0 || tempOffsetMovementManager > 2.0)
            {
                noError = false;
                MessageBox.Show("Number needs to be between 0.0 and 2.0");
            }


            tempSecondsTillMovingDetected = float.Parse(secondsTillMovingDetectedTXT.Text, CultureInfo.InvariantCulture);

            if (tempSecondsTillMovingDetected < 0.0 || tempSecondsTillMovingDetected > 10.0)
            {
                noError = false;
                MessageBox.Show("Number needs to be between 0.0 and 10.0");
            }


            tempOffsetOpenGesture = float.Parse(offsetOpenGestureTXT.Text, CultureInfo.InvariantCulture);

            if (tempOffsetOpenGesture < -2.0 || tempOffsetOpenGesture > 2.0)
            {
                noError = false;
                MessageBox.Show("Number needs to be between -2.0 and 2.0");
            }


            tempMillisecondsTillOpenGestureDetected = int.Parse(milliSecondsTillOpenGestureDetectedTXT.Text, CultureInfo.InvariantCulture);

            if (tempMillisecondsTillOpenGestureDetected < 0 || tempMillisecondsTillOpenGestureDetected > 200)
            {
                noError = false;
                MessageBox.Show("Number needs to be between 0.0 and 10.0");
            }


            tempOffsetHandsBelowWaistLine = float.Parse(offsetHandsBelowWaistLineTXT.Text, CultureInfo.InvariantCulture);

            if (tempOffsetHandsBelowWaistLine < -2.0 || tempOffsetHandsBelowWaistLine > 2.0)
            {
                noError = false;
                MessageBox.Show("Number needs to be between -2.0 and 2.0");
            }


            tempSecondsTillHandBelowWaistLineDetected = float.Parse(SecondsTillHandBelowWaistLineDetectedTXT.Text, CultureInfo.InvariantCulture);

            if (tempSecondsTillHandBelowWaistLineDetected < 0.0 || tempSecondsTillHandBelowWaistLineDetected > 10.0)
            {
                noError = false;
                MessageBox.Show("Number needs to be between 0.0 and 10.0");
            }


            // Slides
            tempOffsetSlideChange = int.Parse(offsetSlideChangeTXT.Text, CultureInfo.InvariantCulture);

            try{

                if (tempOffsetSlideChange < 0 || tempOffsetSlideChange > 10000)
                {
                    noError = false;
                    MessageBox.Show("Number needs to be between 0 and 10000");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Threshold for slide change detected, needs to be an integer! " + ex.Message);
            }

            tempRequiredAveragesToDetectVideo = int.Parse(requiredAveragesToDetectVideoTXT.Text, CultureInfo.InvariantCulture);

            if (tempRequiredAveragesToDetectVideo < 0 || tempRequiredAveragesToDetectVideo > 10)
            {
                noError = false;
                MessageBox.Show("Number needs to be between 0 and 10");
            }


            tempOffsetSkeletonPosition = int.Parse(offsetSkeletonPositionTXT.Text, CultureInfo.InvariantCulture);

            if (tempOffsetSkeletonPosition < 0 || tempOffsetSkeletonPosition > 500)
            {
                noError = false;
                MessageBox.Show("Number needs to be between 0 and 500");
            }

            tempOffsetImageDetected = float.Parse(offsetImageDetectedTXT.Text, CultureInfo.InvariantCulture);

            if (tempOffsetImageDetected < 0.0 || tempOffsetImageDetected > 3.0)
            {
                noError = false;
                MessageBox.Show("Number needs to be between 0 and 50000");
            }

            tempSecondsTillSnapshot = int.Parse(secondsTillSnapshotTXT.Text, CultureInfo.InvariantCulture);


            if (tempSecondsTillSnapshot < 0 || tempSecondsTillSnapshot > 1000)
            {
                noError = false;
                MessageBox.Show("Number needs to be between 0 and 1000");
            }

            tempOffsetVideoDetected = float.Parse(offsetVideoDetectedTXT.Text, CultureInfo.InvariantCulture);


            if (tempOffsetVideoDetected < 0.0 || tempOffsetVideoDetected > 5.0)
            {
                noError = false;
                MessageBox.Show("Number needs to be between 0 and 1000");
            }

            tempThresholdToCalculateOffestForNewShoulderPosition = float.Parse(thresholdToCalculateOffestForNewShoulderPositionTXT.Text, CultureInfo.InvariantCulture);

            if (tempThresholdToCalculateOffestForNewShoulderPosition < 0.0 || tempThresholdToCalculateOffestForNewShoulderPosition > 1.0)
            {
                noError = false;
                MessageBox.Show("Number needs to be between 0 and 1.0");
            }

            tempOffsetHipSkeletonPosition = int.Parse(offsetHipSkeletonPositionTXT.Text, CultureInfo.InvariantCulture);

            if (tempOffsetHipSkeletonPosition < -300 || tempOffsetHipSkeletonPosition > 300)
            {
                noError = false;
                MessageBox.Show("Number needs to be between -300 and 300");
            }

            tempThresholdChangeBorderOfRectangle = int.Parse(thresholdChangeBorderOfRectangleTXT.Text, CultureInfo.InvariantCulture);

            if (tempThresholdChangeBorderOfRectangle < 0 || tempThresholdChangeBorderOfRectangle > 300)
            {
                noError = false;
                MessageBox.Show("Number needs to be between 0 and 300");
            }

            


            if (noError)
            {
                // When creating the xmlProperties object, automatically the object is written as XML to the disk
                XMLproperties.offsetViewingDirection = tempOffsetViewingDirection;
                XMLproperties.secondsLookedAwayDetected = tempSecondsTillLookedAwayDetected;
                XMLproperties.offsetMovementManager = tempOffsetMovementManager;
                XMLproperties.secondsTillMovingDetected = tempSecondsTillMovingDetected;
                XMLproperties.offsetOpenGesture = tempOffsetOpenGesture;
                XMLproperties.milliSecondsTillOpenGestureDetected = tempMillisecondsTillOpenGestureDetected;
                XMLproperties.offsetHandsBelowWaistline = tempOffsetHandsBelowWaistLine;
                XMLproperties.secondsTillHandsBelowwastelineDetected = tempSecondsTillHandBelowWaistLineDetected;
                XMLproperties.offsetSlidesChange = tempOffsetSlideChange;
                XMLproperties.requiredAveragesToDetectVideo = tempRequiredAveragesToDetectVideo;
                XMLproperties.offsetSkeletonPosition = tempOffsetSkeletonPosition;
                XMLproperties.thresholdImageDetected = tempOffsetImageDetected;
                XMLproperties.secondsTillSnapshot = tempSecondsTillSnapshot;
                XMLproperties.thresholdVideoDetected = tempOffsetVideoDetected;
                XMLproperties.thresholdToCalculateOffestForNewShoulderPosition = tempThresholdToCalculateOffestForNewShoulderPosition;
                XMLproperties.offsetHipSkeletonPosition = tempOffsetHipSkeletonPosition;
                XMLproperties.thresholdChangeBorderOfRectangle = tempThresholdChangeBorderOfRectangle;

                XMLproperties.writePropertiesToXML();
                XMLproperties.readPropertiesFromXML();
            }
        }

        private void closeBTN_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }
    }
}
